# Trovo Chat Service - Read from Websocket
# 1. Introduction
Trovo chat service is for applications built by third-party developers to receive and send chat messages to a channel.
(a) Receives chats by connecting to websocket based chat service and keep the persistent connection.
(n) Sends chats through send chat API. (See send chat APIs in Trovo Chat Service (opens new window))
For OAuth and other Trovo APIs please refer to Trovo APIs Developer Doc: Trovo APIs (opens new window)
# 2. Steps to connect chat service websocket
To receive real time chats, you need to create websockets to receive chat messages from one or more channels.
(a) Get a token for chat service. The token will determine which channel or shard or channels you receive chats from. The token would be invalid in 20 seconds.(See section 4.1)
(b) Connect to chat service: Trovo provides a standard websocket protocol wss:// for the chat service. Service address: wss://open-chat.trovo.live/chat
(c) Send AUTH request: Send AUTH request right after successfully connecting to the chat service. Upon successful, the connection will be kept, otherwise, the chat service will be disconnected. (See section 3.1)
(d) Keep persistent connection: Through ping-pong protocol, send heartbeat to our chat service to keep persistent connection. (See section 3.2)
(e) Receive chats: During valid connection, you will receive chats from chat service. (See section 3.3)
# 3. Message structures
Messages are sent in JSON format through websocket. Here is the JSON structure for the chat message:
{
"type": "<string>",
"nonce": "<string>",
"error": "<string>",
"data": "<JSON>"
}
2
3
4
5
6
Field descriptions:
Field name | Description | |
---|---|---|
type | Required | Type of the message. Value options: AUTH, PING, PONG, RESPONSE, CHAT |
nonce | Optional | Random string. Used to match requests and responses. This field is created by the client and returned in the server response. Required for requests sent from the client. |
error | Optional | Error messages returned from the server. |
data | Optional | Data in for the message. The structure of data varies for different message types. |
# 3.1 AUTH message
Upon connecting to the chat service, the client needs to send the request for AUTH immediately, otherwise the client will be disconnected to the chat service.
Request format:
{
"type": "AUTH",
"nonce": "< random string >",
"data": {
"token": "< token from the chat oauth >"
}
}
2
3
4
5
6
7
Response format:
{
"type": "RESPONSE",
"nonce": "<string matching the nounce in the request>"
}
2
3
4
# 3.2 PING-PONG message
In order to keep persistent connection to the chat service. You need to send heartbeat to the server. The recommended frequency is every 30 sec.
Request format:
{
"type": "PING",
"nonce": "<random_string>"
}
2
3
4
Response format:
{
"type": "PONG",
"nonce": "<string matching the nounce in the request>",
"data": {
"gap": 30
}
}
2
3
4
5
6
7
Notice: Gap is sent from the chat service in the response. It is the recommended time period for the client to send heartbeat. Upon receiving the recommended time period, the client should adjust the frequency for sending heartbeat based on the recommendation.
Default recommendation is to send PING every 30 seconds.
# 3.3 CHAT message
Chat messages are sent from the chat server to the client, and the client does not need to respond back to the chat messages.
Chat message structure:
{
"type": "CHAT",
"channel_info": {
"channel_id": "<channel_id>"
},
"data": {
"eid": "<eid>",
"chats": [
{
"type": <message_type_id>,
"content": "<message_txt>",
"nick_name": "<display_name>",
"avatar": "<profile_picture>",
"sub_lv": "<subscription_level>",
"sub_tier": "<subscription_tier>",
"medals": <array_of_badges>,
"decos": <array_of_profile_pic_decors>,
"roles": <array_of_roles>,
"message_id": "<message_id>",
"sender_id": <sender_user_id>,
"send_time":<send_time>,
"uid":<sender_user_id>,
"user_name": "<sender_user_name>",
"content_data":<extra_info_for_message>
}
]
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Field descriptions:
Field name | Type | Description |
---|---|---|
eid | string | Message container ID. This is different from message ID. One message container may contain one or multiple messages. |
chats | Array of chat objects | A list of chats. One chat message may contain multiple chats. |
type | int | Type of chat message. For detailed message types and examples, see section below. |
content | string | Content of the message. Now gift message add new fields, including gift_id, gift_value(unit price of a gift) and value_type(currency type, like Elixir, Mana and so on). |
nick_name | string | Display name of the sender. |
avatar | string | URL of the sender’s profile picture. |
sub_lv | string | The subscription level of the user in the channel. “sub_L1” for level 1 subscriber. |
sub_tier | string | Subscription tier |
medals | string[] | The list of badge names of the sender. |
decos | string[] | The list of decoration names of sender. |
roles | string[] | The list of roles of the message sender. One user can have multiple roles, for example: “roles”:[“mod”, “follower”] |
message_id | string | ID of the message. |
sender_id | int | User ID of the sender. |
send_time | string | send time of the message. |
uid | int | User ID of the sender. |
user_name | string | User name of the sender. |
content_data | map | Extra info of chat, The content_data is different in different chat.(See the table below for the meaning of the content_data fields) |
custom_role | string | The list of role of the message sender which is a json string. Different from "roles", "custom_role" contains more information. However, if you just need the role names, use "roles" instead. |
content_data field descriptions:
Field name | Type | Description |
---|---|---|
custom_emote_enabled | Array of custom emotes objects | List of custom emotes. |
normal_emote_enabled | Array of normal emotes objects | List of normal emotes. |
gift_display_name | string | Display name of gift. |
gift_id | int | Id of gift |
gift_num | int | Number of gifts. |
specialEffectID | int | Id of luxury gift special effect. |
magicChatGiftID | int | Id of Special effects barrage gift. |
rich | string | Rich text. |
chatShowAuth | string | The identity of the user. |
chatViewerThreshold | string | Chat viewer threshold. |
viewers | int | The number of people watching. |
NickName | string | The nickname of the anchor of the gift sub to live broadcast room. |
UserID | string | The user id of the anchor of the gift sub to live broadcast room |
isReSub | int | Distinguish between first-time subscription and re-subscription. 0 - first-time subscription, 1 - re-subscription. |
{
"type": "CHAT",
"channel_info": {
"channel_id": "100000021"
},
"data": {
"eid": "1610095026714481_100000021_2886926419_1",
"chats": [
{
"type": 0,
"content": "Good game!",
"nick_name": "leaf",
"avatar": "exq7kbiaaaaaafch2bzqsjakcy.jpeg?t=3",
"sub_lv": "L1",
"sub_tier": "1",
"medals": [
"sub_L1"
],
"roles": [
"subscriber",
"follower"
],
"message_id": "1610095026391919299_100000021_100000037_2886927498_1",
"sender_id": 100000037,
"send_time": 1612335774,
"uid": 100000037,
"user_name": "leaf",
"content_data":<extra_info_for_message>,
"custom_role":"[{\"roleName\":\"subscriber\",\"roleType\":100004},{\"roleName\":\"follower\",\"roleType\":100006}]"
}
]
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 3.4 Chat Message Types and Samples
Type ID | Description | Sample chat |
---|---|---|
0 | Normal chat messages. | { "type": 0, "content": "text", "nick_name": "ohhh", "avatar": "xxx.png?t=0", "sub_lv": "L3","sub_tier": "1", "medals": ["sub_L3"], "roles": [ "subscriber", "follower" ]} |
5 | Spells, including: mana spells, elixir spells | { "type": 5, "content": "{"gift":"Winner", "num":1}", "nick_name": "wangna", "avatar": "xxx.jpeg?t=8", "sub_lv": "L2", "sub_tier": "1", "medals": [ "creator", "sub_L2"], "roles": ["streamer","subscriber" ]} |
6 | Magic chat - super cap chat | { "type": 6, "content": "super cap.", "nick_name": "ohhh", "avatar": "xxx.png?t=0", "sub_lv": "L3","sub_tier": "1", "medals": ["sub_L3"], "roles": [ "subscriber", "follower" ]} |
7 | Magic chat - colorful chat | { "type": 7, "content": "colorful chat", "nick_name": "ohhh", "avatar": "xxx.png?t=0", "sub_lv": "L3","sub_tier": "1", "medals": ["sub_L3"], "roles": [ "subscriber", "follower" ]} |
8 | Magic chat - spell chat | { "type": 8, "content": "This is a spell chat.", "nick_name": "ohhh", "avatar": "xxx.png?t=0", "sub_lv": "L3","sub_tier": "1", "medals": ["sub_L3"], "roles": [ "subscriber", "follower" ]} |
9 | Magic chat - bullet screen chat | { "type": 9, "content": "bullet screen", "nick_name": "wangna", "avatar": "xxx.jpeg?t=8", "sub_lv": "L2","sub_tier": "1", "medals": [ "creator", "sub_L2"], "roles": ["streamer","subscriber" ]} |
5001 | Subscription message. Shows when someone subscribes to the channel. | { "type": 5001, "content": "has subscribed to the channel!", "nick_name": "mynameislong", "avatar": "xxx.jpeg?t=1", "sub_lv": "L3","sub_tier": "1", "medals": [ "sub_L3" ], "roles": [ "subscriber", "follower" ]} |
5002 | System message. | TBD |
5003 | Follow message. Shows when someone follows the channel. | { "type": 5003, "content": "just followed channel!", "nick_name": "ohhh", "avatar": "xxx.png?t=0", "sub_lv": "L3","sub_tier": "1", "medals": ["sub_L3"], "roles": [ "subscriber", "follower" ]} |
5004 | Welcome message when viewer joins the channel. | { "type": 5004, "content": "just joined channel!", "nick_name": "ohhh", "avatar": "xxx.png?t=0", "sub_lv": "L3","sub_tier": "1", "medals": ["sub_L3"], "roles": [ "subscriber", "follower" ]} |
5005 | Gift sub message. When a user randomly sends gift subscriptions to one or more users in the channel. | { "type": 5005, "content": "2", "nick_name": "flower", "avatar": "5.png", "sub_lv": "L1","sub_tier": "1", "medals": [ "sub_L1" ], "roles": ["subscriber"]}// User “flower” send 2 gift subscriptions randomly to viewers |
5006 | Gift sub message. The detailed messages when a user sends a gift subscription to another user. | { "type": 5006, "content": "100000252,CatKing", "nick_name": "flower", "avatar": "5.png", "sub_lv": "L1","sub_tier": "1", "medals": ["sub_L1"], "roles": [ "subscriber" ]}// User “flower” send a gift subscription to user “CatKing” |
5007 | Activity / events message. For platform level events. | { "type": 5007, "content": "{name} just stepped up to LEVEL {level} ! The Top 3 Spell Point Contributors are: \n#1 {e} #2 {1} #3 {2} ", "nick_name": ""} |
5008 | Welcome message when users join the channel from raid. | { "type": 5008, "content": "{nickname} is carrying {raiderNum} raiders to this channel. Welcome!", "nick_name": "leaf", "avatar": "xxx.jpeg?t=1", "sub_lv": "L3","sub_tier": "1", "medals": ["moderator", "sub_L3"], "roles": [ "mod", "follower" ]} |
5009 | Custom Spells | { "type": 5009, "content": "{"gift":"GiftName", "num":1, "sid":1000001}", "nick_name": "wangna", "avatar": "xxx.jpeg?t=8", "sub_lv": "L2","sub_tier": "1", "medals": [ "creator", "sub_L2"], "roles": ["streamer","subscriber" ]} |
5012 | Stream on/off messages, invisible to the viewers | { "type": 5012, "content": "stream_on", "nick_name": "wangna", "avatar": "xxx.jpeg?t=8", "medals": [ "creator"], "roles": ["streamer","subscriber" ]} |
5013 | Unfollow message. Shows when someone unfollows the channel. | { "type": 5013, "content": "{"name":"unfollow","context":"just unfollowed channel."}", "nick_name": "ohhh", "avatar": "xxx.png?t=0", "sub_lv": "L3","sub_tier": "1", "medals": ["sub_L3"], "roles": ["subscriber", "follower" ]} |
# 3.5 User Roles
Type ID | Roles | Description |
---|---|---|
100000 | streamer | Streamer of the current channel |
100001 | mod | Moderator of the current channel |
100002 | editor | Editor of the current channel |
100004 | subscriber | User who subscribed the current channel |
100005 | supermod | Super moderator of the current channel |
100006 | follower | User who followed of the current channel |
200000 | custom role | User who have a role customized by the streamer of the current channel |
500000 | admin | Admin of Trovo platform, across all channels. |
500001 | warden | Warden of Trovo platform, across all channels, who helps to maintain the platform order. |
300000 | ace | Primary tier of Trovo membership |
300001 | ace+ | Premium tier of Trovo membership |
# 4. Get Chat Token API
OAuth process is required for all APIs and connections of the chat services. Trovo is using OAuth 2.0 for users to grant access to third-party applications. For the more about the OAuth process, please refer to this page. Trovo APIs (opens new window)
# 4.1 Get Chat Token - read chats from my channel only
Gets the token for Trovo chat service. This token allows you to read from the channel of the user that you passed the access token in.
Requested scope: chat_connect
Request access token: Yes
HTTP request type:GET
Request:
curl \
-H 'Accept: application/json' \
-H 'Client-ID: <your_client_id>' \
-H 'Authorization: OAuth <access_token>' \
-X GET 'https://open-api.trovo.live/openplatform/chat/token'
2
3
4
5
Sample Response:
{ "token": "xxxxxxxxxxxxxxx="}
# 4.2 Get Chat Channel Token - from any selected channel
Gets the token for Trovo chat service. This allows you to pass in the channel ID and read chats from this specific channel. No scope or access token required.
Requested scope: None.
Request access token: No.
Request URL Params:
Param | Description | |
---|---|---|
Channel ID | required | ID of the target channel. |
Request Format:
curl \
-H 'Accept: application/json' \
-H 'Client-ID: < your_client_id >' \
-X GET 'https://open-api.trovo.live/openplatform/chat/channel-token/{channelID}'
2
3
4
Request Sample:
curl \
-H 'Accept: application/json' \
-H 'Client-ID: <your_client_id>' \
-X GET 'https://open-api.trovo.live/openplatform/chat/channel-token/100000021'
2
3
4
Sample Response:
{ "token": "xxxxxxxxxxxxxxx="}
# 4.3 Get Chat Shard Token - read from multiple channels
Gets the token of the shard that is used for reading chat messages from multiple channels. (For how sharding works, please read section 5).
Requested scope: None
Request access token: No
Request Params:
Param | Type | Description |
---|---|---|
total_shard | int | Total number of shards. total_shard > 0. |
current_shard | int | The shard_id of the current shard you want to read. 0 <= current_shard < total_shard |
Request Format:
curl \
-H 'Accept: application/json' \
-H 'Client-ID: <client_id>’ \
-X GET 'https://open-api.trovo.live/openplatform/chat/shard-token?current_shard={current_shard}&total_shard={total_shard}'
2
3
4
Request Sample:
curl \
-H 'Accept: application/json' \
-H 'Client-ID: <your_client_id>’ \
-X GET 'https://open-api.trovo.live/openplatform/chat/shard-token?current_shard=1&total_shard=3'
2
3
4
Response Sample - Success, get token:
{"token":"xxxxxxxxxxx"}
Response Sample - Failed, invalid shard value:
{
"status": 11708,
"error": "Internal Server Error",
"message": "Invalid shard value (Please make sure total_shard > 0 and 0 <= current_shard < total_shard)"
}
2
3
4
5
# 5. Sharding - Read chats from multiple channels
You may read chat messages from multiple channels through one websocket. Here we use sharding, a simple way to divide channels into shards and each websockets will be sending all the chats from channels in this current shard.
Sharding Formula:
shard_id = channel_id % total_shard
Param | Type | Description |
---|---|---|
total_shard | int | Total number of shards. total_shard > 0. |
current_shard | int | The shard_id of the current shard you want to read. 0 <= current_shard < total_shard |
channel_id | int | The id of the channel, also the user id of the streamer. |
For example if you set total_shard to 3, then all the channels will be divided into 3 shards, shard_id 0, 1 and 2. Shard 0 will contain all channels with channel id % 3 = 0. Shard 1 contains all channels with channel id % 3 = 1. And channel 2 contains all channels with channel id % 3 = 2. Larger total_shard means less channels in one shard.